import functools

@functools.total_ordering
class PSSection(object):
    def __init__(self, **kw):
        object.__setattr__(self, "_items", kw.copy())
        object.__setattr__(self, "_anonimousSections", [])

    def append(self, p):
        self._anonimousSections.append(p)

    def extend(self, p):
        self._anonimousSections.extend(p)

    def copy(self):
        res = PSSection(**self._items)
        object.__setattr__(res, "_anonimousSections", [p.copy() for p in self._anonimousSections])
        return res

    def __getattr__(self, name):
        items = object.__getattribute__(self, "_items")
        return items[name]

    def __setattr__(self, name, value):
        items = object.__getattribute__(self, "_items")
        items[name] = value

    def __delattr__(self, name):
        items = object.__getattribute__(self, "_items")
        del items[name]

    def __len__(self):
        return len(self._anonimousSections)

    def __iter__(self):
        return self._anonimousSections.__iter__()

    def __getitem__(self, index):
        if isinstance(index, (int, slice)):
            return self._anonimousSections[index]
        return self._items[index]

    def __setitem__(self, key, value):
        if isinstance(key, (int, slice)):
            self._anonimousSections[key] = value
        else:
            self._items[key] = value

    def __delitem__(self, index):
        del self._anonimousSections[index]

    def __repr__(self):
        vars = []
        for k, v in self._items.items():
            vars.append((k, repr(v)))

        vars = '; '.join(["%s = %s" % p for p in vars])

        if not self._anonimousSections:
            return "PSSection(%s)" % vars

        return "PSSection(%s; %s)" % (vars, '; '.join(map(repr, self._anonimousSections)))

    def __hash__(self):
        res = 0
        for k, v in sorted(self._items.items()):
            res ^= k.__hash__() ^ v.__hash__()

        for p in self._anonimousSections:
            res ^= p.__hash__()

        return res

    def __eq__(self, p):
        a_items = self._items
        b_items = p._items

        if len(a_items) != len(b_items):
            return False

        a_items = sorted(a_items.items())
        b_items = sorted(b_items.items())

        for (ka, va), (kb, vb) in zip(a_items, b_items):
            if ka != kb or va != vb:
                return False

        a_sects = self._anonimousSections
        b_sects = p._anonimousSections
        if len(a_sects) != len(b_sects):
            return False

        for sa, sb in zip(a_sects, b_sects):
            if sa != sb:
                return False

        return True

    def __ne__(self, p):
        return not self.__eq__(p)

    def __lt__(self, p):
        a_items = self._items
        b_items = p._items

        if len(a_items) != len(b_items):
            return len(a_items) < len(b_items)

        a_items = sorted(a_items.items())
        b_items = sorted(b_items.items())

        for (ka, va), (kb, vb) in zip(a_items, b_items):
            if ka != kb:
                return ka < kb
            if va != vb:
                return va < vb

        a_sects = self._anonimousSections
        b_sects = p._anonimousSections
        if len(a_sects) != len(b_sects):
            return len(a_sects) < len(b_sects)

        for sa, sb in zip(a_sects, b_sects):
            if sa != sb:
                return sa < sb

        return False

  